﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace eTMS.Controls
{
    public partial class MyChart : Control
    {
        static string chartType = "Line";

        private float W;
        private float H;

        private float n;
        private Image image;

        private ArrayList values1 = new ArrayList();
        string name1 = null;
        private ArrayList values2 = new ArrayList();
        string name2 = null;
        private ArrayList values3 = new ArrayList();
        string name3 = null;
        private ArrayList values4 = new ArrayList();
        string name4 = null;
        private ArrayList values5 = new ArrayList();
        string name5 = null;

        private ArrayList axisXValues = new ArrayList();


        ArrayList pieValues = new ArrayList();
        ArrayList pieNames = new ArrayList();



        static internal Brush brush1 = Brushes.Red;
        static internal Brush brush2 = Brushes.Green;
        static internal Brush brush3 = Brushes.Blue;
        static internal Brush brush4 = Brushes.Brown;
        static internal Brush brush5 = Brushes.Orange;
        static internal Brush brush6 = Brushes.Pink;
        static internal Brush brush7 = Brushes.Violet;
        static internal Brush brush8 = Brushes.Gold;
        static internal Brush brush9 = Brushes.DarkOrchid;
        static internal Brush brush10 = Brushes.YellowGreen;

        static internal Brush chartTitleColor = Brushes.Black;
        static internal Brush xAxisTitleColor = Brushes.Black;
        static internal Brush yAxisTitleColor = Brushes.Black;


        private bool HLines;
        private bool VLines;
        string chartTitle = "";
        string xAxisTitle = "";
        string yAxisTitle = "";




        private Point mouseOffset;

        float stepx = 1;
        float stepy = 1;

        int verticalLineMax = 0;

        float min_val = 0;
        float max_val = 0;


        public MyChart()
        {

        }
        private void CreateImage()
        {
            if (this.image != null)
            {
                this.image.Dispose();
            }
            this.image = new Bitmap(this.Width, this.Height);
        }
        public void LoadXAsisTitle(string[] arrayXTitles)
        {
            axisXValues.Clear();
            axisXValues.AddRange(arrayXTitles);
        }
        private void MyChart_Load(object sender, EventArgs e)
        {
        }
        public void DoPaint()
        {
            try
            {
                this.CreateImage();
                if (chartType == "Line")
                    PaintLineChart();
                else if (chartType == "Column")
                    PaintColumnChart();
                else if (chartType == "Pie")
                    PaintPieChart();
                else if (chartType == "Scatter")
                    PaintScatterChart();
                this.BackgroundImage = image;
                this.Invalidate();
            }
            catch
            {
            }
        }



        // Properties for data members of this class

        public bool VerticalLines
        {
            get
            {
                return VLines;
            }
            set
            {
                VLines = value;
            }
        }

        public bool HorizontalLines
        {
            get
            {
                return HLines;
            }
            set
            {
                HLines = value;
            }
        }

        public string ChartType
        {
            get
            {
                return chartType;
            }
            set
            {
                chartType = value;
            }
        }
        public string ChartTitle
        {
            get
            {
                return chartTitle;
            }
            set
            {
                chartTitle = value;
            }
        }
        public string XAxisTitle
        {
            get
            {
                return xAxisTitle;
            }
            set
            {
                xAxisTitle = value;
            }
        }
        public string YAxisTitle
        {
            get
            {
                return yAxisTitle;
            }
            set
            {
                yAxisTitle = value;
            }
        }


        // Method to draw a column chart
        // Input : void
        // Output : void
        public void PaintColumnChart()
        {

            int column = 0;

            if (this.Width < 300)
                this.Width = 300;
            if (this.Height < 200)
                this.Height = 200;


            W = this.Width - (20 + 40 + 20 + 120);
            H = this.Height - 50;


            Graphics graph = Graphics.FromImage(image);
            graph.Clear(Color.White);
            Pen penCurrent = new Pen(Color.Black, 2);
            Rectangle Rect = new Rectangle(0, 0, (int)this.Width, (int)this.Height);

            graph.DrawRectangle(penCurrent, Rect);

            penCurrent = new Pen(Color.Black);

            graph.DrawLine(penCurrent, new Point(65, 20), new Point(65, (int)(H + 20)));
            graph.DrawLine(penCurrent, new Point(65, (int)(H + 20)), new Point((int)(W + 60), (int)(H + 20)));


            stepx = 1;
            stepy = 1;

            verticalLineMax = 0;

            min_val = 0;
            max_val = 0;

            float stepValue = 1;

            for (int i = 0; i < values1.Count; i++)
            {
                if (min_val > (float)values1[i])
                    min_val = (float)values1[i];
                if (max_val < (float)values1[i])
                    max_val = (float)values1[i];
            }

            for (int i = 0; i < values2.Count; i++)
            {
                if (min_val > (float)values2[i])
                    min_val = (float)values2[i];
                if (max_val < (float)values2[i])
                    max_val = (float)values2[i];
            }

            for (int i = 0; i < values3.Count; i++)
            {
                if (min_val > (float)values3[i])
                    min_val = (float)values3[i];
                if (max_val < (float)values3[i])
                    max_val = (float)values3[i];
            }
            for (int i = 0; i < values4.Count; i++)
            {
                if (min_val > (float)values4[i])
                    min_val = (float)values4[i];
                if (max_val < (float)values4[i])
                    max_val = (float)values4[i];
            }
            for (int i = 0; i < values5.Count; i++)
            {
                if (min_val > (float)values5[i])
                    min_val = (float)values5[i];
                if (max_val < (float)values5[i])
                    max_val = (float)values5[i];
            }




            stepValue = max_val / 10;

            stepy = (H) / 10;
            verticalLineMax = (int)(H + 20 - (10 * stepy));
            for (int i = 1; i <= 10; i++)
            {
                graph.DrawLine(penCurrent, new Point(63, (int)(H + 20 - i * stepy)), new Point(67, (int)(H + 20 - i * stepy)));
                string title = "";

                if (max_val < 1)
                    title = ((float)(stepValue * i)).ToString();
                else
                    title = ((int)(stepValue * i)).ToString();

                graph.DrawString(title, new Font(FontFamily.GenericSansSerif, 7), Brushes.Black, 20, (float)(H + 20 - i * stepy) - 6);
                if (HLines)
                {
                    Pen pl = new Pen(Color.LightGray);
                    pl.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
                    graph.DrawLine(pl, new Point(65, (int)(H + 20 - i * stepy)), new Point((int)(W + 60), (int)(H + 20 - i * stepy)));
                }
            }


            if (values1.Count > 0)
                stepx = (int)(W) / (values1.Count + 1);
            else if (values2.Count > 0)
                stepx = (int)(W) / (values2.Count + 1);
            else if (values3.Count > 0)
                stepx = (int)(W) / (values3.Count + 1);

            else if (values4.Count > 0)
                stepx = (int)(W) / (values4.Count + 1);

            else if (values5.Count > 0)
                stepx = (int)(W) / (values5.Count + 1);

            else return;




            for (int i = 1; i <= values1.Count; i++)
            {

                graph.DrawLine(penCurrent, new Point((int)(i * stepx + 65), (int)(H + 20 - 2)), new Point((int)(i * stepx + 65), (int)(H + 20 + 2)));
                string title = "";
                if (i <= axisXValues.Count)
                {
                    title = axisXValues[i - 1].ToString();
                }
                else
                {
                    title = i.ToString();
                }
                graph.DrawString(title, new Font(FontFamily.GenericSansSerif, 7), Brushes.Black, (float)(i * stepx + 65 - 7), (float)(H + 20 + 5));
                if (VLines)
                {
                    Pen pl = new Pen(Brushes.Gray, 1);
                    pl.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
                    graph.DrawLine(pl, new Point((int)(i * stepx + 65), (int)(H + 20)), new Point((int)(i * stepx + 65), (int)verticalLineMax));
                }

            }


            // Column for values1
            int legendTop = 20 + 20;


            if (values1.Count >= 1)
            {
                DrawColumn(values1, name1, brush1, graph, column, ref legendTop);
                column++;
            }

            if (values2.Count >= 1)
            {
                DrawColumn(values2, name2, brush2, graph, column, ref legendTop);
                column++;
            }
            if (values3.Count >= 1)
            {
                DrawColumn(values3, name3, brush3, graph, column, ref legendTop);
                column++;
            }
            if (values4.Count >= 1)
            {
                DrawColumn(values4, name4, brush4, graph, column, ref legendTop);
                column++;
            }
            if (values5.Count >= 1)
            {
                DrawColumn(values5, name5, brush5, graph, column, ref legendTop);
                column++;
            }

            if (column == 0)
            {
                graph.DrawRectangle(Pens.Black, 65, 20, W + 60, H + 20);
                graph.DrawString("Không có dữ liệu", new Font(FontFamily.GenericSansSerif, 12), Brushes.Black, 60 + 20, 20 + 40);

            }

            if (chartTitle != "")
                graph.DrawString(chartTitle, new Font(FontFamily.GenericSansSerif, 9), chartTitleColor, (int)((60 + W + 20 + 60) / 2), 2);
            if (xAxisTitle != "")
                graph.DrawString(xAxisTitle, new Font(FontFamily.GenericSansSerif, 7), xAxisTitleColor, (int)((60 + W + 20 + 60) / 2), 20 + H + 13);
            if (yAxisTitle != "")
            {
                StringFormat format = new StringFormat();
                format.FormatFlags = StringFormatFlags.DirectionVertical;
                graph.DrawString(yAxisTitle, new Font(FontFamily.GenericSansSerif, 7), yAxisTitleColor, 4, 20, format);
            }



        }

        // Methpod to draw columns on fixed points on a column chart
        // Input : graphics object on which we want to write, an array of values, a name for this series , a brush represents the color of the points to be drawn 
        //         and the integer value represents the height that is to be used while drawing legends of the chart and an integer value represents the width that is to be considered when drawing chrt without overlaping columns. 
        // Output : void
        public void DrawColumn(ArrayList values, string name, Brush brush, Graphics graph, int column, ref int legendTop)
        {

            bool WriteLegend = false;
            if (values.Count > 1)
            {

                Point[] v = new Point[values.Count];

                for (int i = 0; i < values.Count; i++)
                {
                    v[i].X = (int)((i + 1) * stepx + 65);

                    float proc = (100 * (float)values[i]) / (max_val);
                    v[i].Y = (int)(verticalLineMax + (((H) * (100 - proc)) / 100));

                    int start = v[i].X + (column * 7);

                    graph.FillRectangle(brush, start, v[i].Y, 7, ((H + 20) - (verticalLineMax + (((H) * (100 - proc)) / 100))));

                    if (WriteLegend == false)
                    {
                        Rectangle rect = new Rectangle((int)W + 60 + 20, legendTop, 10, 10);
                        graph.FillRectangle(brush, rect);
                        graph.DrawString(name, new Font(FontFamily.GenericSansSerif, 7), Brushes.Black, (W + 60 + 20 + 10 + 5), legendTop);
                        legendTop += 15;
                        WriteLegend = true;

                    }
                }


            }

        }

        // Method to draw a pie chart
        // Input : void
        // Output : void
        public void PaintPieChart()
        {

            // if (this.Height > 320)
            //    this.Height = 320;

            W = this.Width - (20 + 40 + 20 + 120);
            H = this.Height - (20 + 20);
            W = Math.Min(W, H);
            H = W;


            Graphics graph = Graphics.FromImage(image);
            graph.Clear(Color.White);
            Pen penCurrent = new Pen(Color.Black, 2);
            Rectangle Rect = new Rectangle(0, 0, (int)this.Width, (int)this.Height);

            graph.DrawRectangle(penCurrent, Rect);

            penCurrent = new Pen(Color.Gray);
            Rect = new Rectangle(60, 20, (int)W, (int)H);

            graph.DrawRectangle(penCurrent, Rect);

            graph.DrawRectangle(penCurrent, Rect);


            Brush[] brushes = new Brush[20];
            brushes[0] = brush1;
            brushes[1] = brush2;
            brushes[2] = brush3;
            brushes[3] = brush4;
            brushes[4] = brush5;
            brushes[5] = brush6;
            brushes[6] = brush7;
            brushes[7] = brush8;
            brushes[8] = brush9;
            brushes[9] = brush10;




            // Sum the inputs to get the total
            float total = 0.0f;
            foreach (object o in pieValues)
            {
                float val = (float)o;
                total += val;
            }
            // Draw the pie chart
            float start = 0.0f;
            float end = 0.0f;
            float current = 0.0f;

            if (pieValues.Count == 0)
                graph.DrawString("Không có dữ liệu", new Font(FontFamily.GenericSansSerif, 12), chartTitleColor, 60 + 20, 20 + 40);

            int legendTop = 20 + 20;

            for (int i = 0; i < pieValues.Count; i++)
            {
                current += (float)pieValues[i];
                start = end;
                end = (float)(current / total) * 360.0f;

                graph.FillPie(brushes[i % 20], 65, 20, W,
                    H, start, end - start);


                Rectangle rect = new Rectangle((int)W + 60 + 20, legendTop, 10, 10);
                graph.FillRectangle(brushes[i % 20], rect);
                graph.DrawString(pieNames[i].ToString(), new Font(FontFamily.GenericSansSerif, 7), Brushes.Black, (W + 60 + 20 + 10 + 5), legendTop);
                legendTop += 15;

            }
            if (chartTitle != "")
                graph.DrawString(chartTitle, new Font(FontFamily.GenericSansSerif, 9), chartTitleColor, (int)((60 + W + 20 + 60) / 2), 2);
            if (xAxisTitle != "")
                graph.DrawString(xAxisTitle, new Font(FontFamily.GenericSansSerif, 7), xAxisTitleColor, (int)((60 + W + 20 + 60) / 2), 20 + H + 13);
            if (yAxisTitle != "")
            {
                StringFormat format = new StringFormat();
                format.FormatFlags = StringFormatFlags.DirectionVertical;
                graph.DrawString(yAxisTitle, new Font(FontFamily.GenericSansSerif, 7), yAxisTitleColor, 10, 20, format);
            }





        }



        // Method to draw a Line chart
        // Input : void
        // Output : void
        public void PaintLineChart()
        {


            if (this.Width < 300)
                this.Width = 300;
            if (this.Height < 200)
                this.Height = 200;

            //if (this.Height > 320)
            //    this.Height = 320;

            W = this.Width - (20 + 40 + 20 + 120);
            H = this.Height - 50;


            Graphics graph = Graphics.FromImage(image);
            graph.Clear(Color.White);
            Pen penCurrent = new Pen(Color.Black, 2);
            Rectangle Rect = new Rectangle(0, 0, (int)this.Width, (int)this.Height);

            graph.DrawRectangle(penCurrent, Rect);

            penCurrent = new Pen(Color.Black);

            graph.DrawLine(penCurrent, new Point(65, 20), new Point(65, (int)(H + 20)));
            graph.DrawLine(penCurrent, new Point(65, (int)(H + 20)), new Point((int)(W + 60), (int)(H + 20)));



            stepx = 1;
            stepy = 1;


            verticalLineMax = 0;

            min_val = 0;
            max_val = 0;

            float stepValue = 1;


            for (int i = 0; i < values1.Count; i++)
            {
                if (min_val > (float)values1[i])
                    min_val = (float)values1[i];
                if (max_val < (float)values1[i])
                    max_val = (float)values1[i];
            }

            for (int i = 0; i < values2.Count; i++)
            {
                if (min_val > (float)values2[i])
                    min_val = (float)values2[i];
                if (max_val < (float)values2[i])
                    max_val = (float)values2[i];
            }

            for (int i = 0; i < values3.Count; i++)
            {
                if (min_val > (float)values3[i])
                    min_val = (float)values3[i];
                if (max_val < (float)values3[i])
                    max_val = (float)values3[i];
            }
            for (int i = 0; i < values4.Count; i++)
            {
                if (min_val > (float)values4[i])
                    min_val = (float)values4[i];
                if (max_val < (float)values4[i])
                    max_val = (float)values4[i];
            }
            for (int i = 0; i < values5.Count; i++)
            {
                if (min_val > (float)values5[i])
                    min_val = (float)values5[i];
                if (max_val < (float)values5[i])
                    max_val = (float)values5[i];
            }



            stepValue = max_val / 10;

            stepy = (H) / 10;

            verticalLineMax = (int)(H + 20 - (10 * stepy));

            for (int i = 1; i <= 10; i++)
            {
                graph.DrawLine(penCurrent, new Point(63, (int)(H + 20 - i * stepy)), new Point(67, (int)(H + 20 - i * stepy)));
                if (max_val < 1)
                    graph.DrawString(((float)(stepValue * i)).ToString(), new Font(FontFamily.GenericSansSerif, 7), Brushes.Black, 20, (float)(H + 20 - i * stepy) - 6);
                else
                    graph.DrawString(((int)(stepValue * i)).ToString(), new Font(FontFamily.GenericSansSerif, 7), Brushes.Black, 20, (float)(H + 20 - i * stepy) - 6);
                if (HLines)
                {
                    Pen pl = new Pen(Color.LightGray);
                    pl.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
                    graph.DrawLine(pl, new Point(65, (int)(H + 20 - i * stepy)), new Point((int)(W + 60), (int)(H + 20 - i * stepy)));
                }
            }

            if (values1.Count > 0)
                stepx = (int)(W) / values1.Count;
            else if (values2.Count > 0)
                stepx = (int)(W) / values2.Count;
            else if (values3.Count > 0)
                stepx = (int)(W) / values3.Count;

            else if (values4.Count > 0)
                stepx = (int)(W) / values4.Count;

            else if (values5.Count > 0)
                stepx = (int)(W) / values5.Count;

            else
            {
                graph.DrawString("Không có dữ liệu", new Font(FontFamily.GenericSansSerif, 12), chartTitleColor, 60 + 20, 20 + 40);
                return;
            }

            for (int i = 1; i <= values1.Count; i++)
            {
                graph.DrawLine(penCurrent, new Point((int)(i * stepx + 65), (int)(H + 20 - 2)), new Point((int)(i * stepx + 65), (int)(H + 20 + 2)));
                string title = "";

                if (i <= axisXValues.Count)
                    title = axisXValues[i-1].ToString();
                else
                    title = i.ToString();
                graph.DrawString(title, new Font(FontFamily.GenericSansSerif, 7), Brushes.Black, (float)(i * stepx + 65 - 7), (float)(H + 20 + 5));
                if (VLines)
                {
                    Pen pl = new Pen(Brushes.Gray, 1);
                    pl.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
                    graph.DrawLine(pl, new Point((int)(i * stepx + 65), (int)(H + 20)), new Point((int)(i * stepx + 65), (int)verticalLineMax));
                }
            }



            int legendTop = 20 + 20;

            bool written = false;

            if (values1.Count > 1)
            {
                DrawLine(graph, values1, name1, brush1, ref legendTop);
                written = true;

            }
            if (values2.Count > 1)
            {
                DrawLine(graph, values2, name2, brush2, ref legendTop);
                written = true;

            }
            if (values3.Count > 1)
            {
                DrawLine(graph, values3, name3, brush3, ref legendTop);
                written = true;
            }
            if (values4.Count > 1)
            {
                DrawLine(graph, values4, name4, brush4, ref legendTop);
                written = true;
            }
            if (values5.Count > 1)
            {
                DrawLine(graph, values5, name5, brush5, ref legendTop);
                written = true;
            }

            if (written == false)
            {
                graph.DrawString("", new Font(FontFamily.GenericSansSerif, 12), chartTitleColor, 60 + 20, 20 + 40);
                return;
            }

            if (chartTitle != "")
                graph.DrawString(chartTitle, new Font(FontFamily.GenericSansSerif, 9), chartTitleColor, (int)((60 + W + 20 + 60) / 2), 2);
            if (xAxisTitle != "")
                graph.DrawString(xAxisTitle, new Font(FontFamily.GenericSansSerif, 7), xAxisTitleColor, (int)((60 + W + 20 + 60) / 2), 20 + H + 13);
            if (yAxisTitle != "")
            {
                StringFormat format = new StringFormat();
                format.FormatFlags = StringFormatFlags.DirectionVertical;
                graph.DrawString(yAxisTitle, new Font(FontFamily.GenericSansSerif, 7), yAxisTitleColor, 4, 20, format);
            }




        }

        // Methpod to draw lines on fixed points on a Line chart
        // Input : graphics object on which we want to write, an array of values, a name for this series , a brush represents the color of the points to be drawn 
        //         and the integer value represents the height that is to be used while drawing legends of the chart.
        // Output : void
        public void DrawLine(Graphics graph, ArrayList values, string name, Brush brush, ref int legendTop)
        {
            Pen pp = new Pen(brush, 1);
            Point[] v = new Point[values.Count];
            bool WriteLegend = false;

            for (int i = 0; i < values.Count; i++)
            {
                v[i].X = (int)((i + 1) * stepx + 65);

                float proc = (100 * (float)values[i]) / (max_val);
                v[i].Y = (int)(verticalLineMax + (((H) * (100 - proc)) / 100));

                //v[i].Y=(int)(H+20-proc);

                graph.FillRectangle(brush, v[i].X - 2, v[i].Y - 2, 5, 5);
                if (WriteLegend == false)
                {
                    Rectangle rect = new Rectangle((int)W + 60 + 20, legendTop, 10, 10);
                    graph.FillRectangle(brush, rect);
                    graph.DrawString(name, new Font(FontFamily.GenericSansSerif, 7), Brushes.Black, (W + 60 + 20 + 10 + 5), legendTop);

                    legendTop += 15;
                    WriteLegend = true;
                }
            }

            graph.DrawLines(pp, v);

        }

        // Method to draw a Scatter chart
        // Input : void
        // Output : void
        public void PaintScatterChart()
        {


            if (this.Width < 300)
                this.Width = 300;
            if (this.Height < 200)
                this.Height = 200;

            // if (this.Height > 320)
            //     this.Height = 320;

            W = this.Width - (20 + 40 + 20 + 120);
            H = this.Height - 50;


            Graphics graph = Graphics.FromImage(image);
            graph.Clear(Color.White);
            Pen penCurrent = new Pen(Color.Black, 2);
            Rectangle Rect = new Rectangle(0, 0, (int)this.Width, (int)this.Height);

            graph.DrawRectangle(penCurrent, Rect);

            penCurrent = new Pen(Color.Black);

            graph.DrawLine(penCurrent, new Point(65, 20), new Point(65, (int)(H + 20)));
            graph.DrawLine(penCurrent, new Point(65, (int)(H + 20)), new Point((int)(W + 60), (int)(H + 20)));



            stepx = 1;
            stepy = 1;

            verticalLineMax = 0;

            min_val = 0;
            max_val = 0;

            float stepValue = 1;


            for (int i = 0; i < values1.Count; i++)
            {
                if (min_val > (float)values1[i])
                    min_val = (float)values1[i];
                if (max_val < (float)values1[i])
                    max_val = (float)values1[i];
            }

            for (int i = 0; i < values2.Count; i++)
            {
                if (min_val > (float)values2[i])
                    min_val = (float)values2[i];
                if (max_val < (float)values2[i])
                    max_val = (float)values2[i];
            }

            for (int i = 0; i < values3.Count; i++)
            {
                if (min_val > (float)values3[i])
                    min_val = (float)values3[i];
                if (max_val < (float)values3[i])
                    max_val = (float)values3[i];
            }
            for (int i = 0; i < values4.Count; i++)
            {
                if (min_val > (float)values4[i])
                    min_val = (float)values4[i];
                if (max_val < (float)values4[i])
                    max_val = (float)values4[i];
            }
            for (int i = 0; i < values5.Count; i++)
            {
                if (min_val > (float)values5[i])
                    min_val = (float)values5[i];
                if (max_val < (float)values5[i])
                    max_val = (float)values5[i];
            }



            stepValue = (int)max_val / 10;


            stepy = (H) / 10;

            verticalLineMax = (int)(H + 20 - (10 * stepy));

            for (int i = 1; i <= 10; i++)
            {
                graph.DrawLine(penCurrent, new Point(63, (int)(H + 40 - i * stepy)), new Point(67, (int)(H + 20 - i * stepy)));
                if (max_val < 1)
                    graph.DrawString(((float)(stepValue * i)).ToString(), new Font(FontFamily.GenericSansSerif, 7), Brushes.Black, 20, (float)(H + 20 - i * stepy) - 6);
                else
                    graph.DrawString(((int)(stepValue * i)).ToString(), new Font(FontFamily.GenericSansSerif, 7), Brushes.Black, 20, (float)(H + 20 - i * stepy) - 6);

                if (HLines)
                {
                    Pen pl = new Pen(Color.LightGray);
                    pl.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
                    graph.DrawLine(pl, new Point(65, (int)(H + 20 - i * stepy)), new Point((int)(W + 60), (int)(H + 20 - i * stepy)));
                }
            }


            if (values1.Count > 0)
                stepx = (int)(W) / values1.Count;
            else if (values2.Count > 0)
                stepx = (int)(W) / values2.Count;
            else if (values3.Count > 0)
                stepx = (int)(W) / values3.Count;

            else if (values4.Count > 0)
                stepx = (int)(W) / values4.Count;

            else if (values5.Count > 0)
                stepx = (int)(W) / values5.Count;
            else
            {
                graph.DrawString("Không có dữ liệu", new Font(FontFamily.GenericSansSerif, 12), chartTitleColor, 60 + 20, 20 + 40);
                return;
            }

            for (int i = 1; i <= values1.Count; i++)
            {
                graph.DrawLine(penCurrent, new Point((int)(i * stepx + 65), (int)(H + 20 - 2)), new Point((int)(i * stepx + 65), (int)(H + 20 + 2)));
                graph.DrawString(i.ToString(), new Font(FontFamily.GenericSansSerif, 7), Brushes.Black, (float)(i * stepx + 65 - 7), (float)(H + 20 + 5));
                if (VLines)
                {
                    Pen pl = new Pen(Brushes.Gray, 1);
                    pl.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
                    graph.DrawLine(pl, new Point((int)(i * stepx + 65), (int)(H + 20)), new Point((int)(i * stepx + 65), (int)verticalLineMax));
                }
            }

            int legendTop = 20 + 20;

            bool written = false;

            if (values1.Count > 0)
            {
                DrawPoints(graph, values1, name1, brush1, ref legendTop);
                written = true;
            }
            if (values2.Count > 1)
            {
                DrawPoints(graph, values2, name2, brush2, ref legendTop);
                written = true;
            }
            if (values3.Count > 1)
            {
                DrawPoints(graph, values3, name3, brush3, ref legendTop);
                written = true;
            }
            if (values4.Count > 1)
            {
                DrawPoints(graph, values4, name4, brush4, ref legendTop);
                written = true;
            }
            if (values5.Count > 1)
            {
                DrawPoints(graph, values5, name5, brush5, ref legendTop);
                written = true;
            }

            if (written == false)
            {
                graph.DrawString("", new Font(FontFamily.GenericSansSerif, 12), chartTitleColor, 60 + 20, 20 + 40);
                return;
            }

            if (chartTitle != "")
                graph.DrawString(chartTitle, new Font(FontFamily.GenericSansSerif, 9), chartTitleColor, (int)((60 + W + 20 + 60) / 2), 2);
            if (xAxisTitle != "")
                graph.DrawString(xAxisTitle, new Font(FontFamily.GenericSansSerif, 7), xAxisTitleColor, (int)((60 + W + 20 + 60) / 2), 20 + H + 13);
            if (yAxisTitle != "")
            {
                StringFormat format = new StringFormat();
                format.FormatFlags = StringFormatFlags.DirectionVertical;
                graph.DrawString(yAxisTitle, new Font(FontFamily.GenericSansSerif, 7), yAxisTitleColor, 4, 20, format);
            }

        }


        // Methpod to draw points on fixed points on a scatter chart
        // Input : graphics object on which we want to write, an array of values, a name for this series , a brush represents the color of the points to be drawn 
        //         and the integer value represents the height that is to be used while drawing legends of the chart.
        // Output : void
        public void DrawPoints(Graphics graph, ArrayList values, string name, Brush brush, ref int legendTop)
        {
            Pen pp = new Pen(brush, 1);
            Point[] v = new Point[values.Count];
            bool WriteLegend = false;

            for (int i = 0; i < values.Count; i++)
            {
                v[i].X = (int)((i + 1) * stepx + 65);

                float proc = (100 * (float)values[i]) / (max_val);
                v[i].Y = (int)(verticalLineMax + (((H) * (100 - proc)) / 100));


                graph.FillRectangle(brush, v[i].X - 2, v[i].Y - 2, 5, 5);
                if (WriteLegend == false)
                {
                    Rectangle rect = new Rectangle((int)W + 60 + 20, legendTop, 10, 10);
                    graph.FillRectangle(brush, rect);
                    graph.DrawString(name, new Font(FontFamily.GenericSansSerif, 7), Brushes.Black, (W + 60 + 20 + 10 + 5), legendTop);
                    legendTop += 15;
                    WriteLegend = true;

                }

            }


        }

        public void ResizeToOriginal()
        {
            if (this.Width > 320)
                this.Width = 320;
            if (this.Height > 240)
                this.Height = 240;

        }

        // Method to load values of ArrayLists 
        // Note : These values are used while drawing charts.
        //        5 arrays of values is because the maximum number of fields used to draw the chart is 5.  
        // Input : 5 arrays of type float and 5 names for these 5 array values 
        // Output : void
        public void LoadValues(float[] v1, string n1, float[] v2, string n2, float[] v3, string n3, float[] v4, string n4, float[] v5, string n5)
        {
            values1.Clear();
            values2.Clear();
            values3.Clear();
            values4.Clear();
            values5.Clear();


            if (v1 != null && n1 != null)
            {
                foreach (float f in v1)
                {
                    values1.Add(f);
                }
                name1 = n1;
            }
            if (v2 != null && n2 != null)
            {
                foreach (float f in v2)
                {
                    values2.Add(f);
                }
                name2 = n2;
            }
            if (v3 != null && n3 != null)
            {
                foreach (float f in v3)
                {
                    values3.Add(f);
                }
                name3 = n3;
            }
            if (v4 != null && n4 != null)
            {
                foreach (float f in v4)
                {
                    values4.Add(f);
                }
                name4 = n4;
            }
            if (v5 != null && n5 != null)
            {
                foreach (float f in v5)
                {
                    values5.Add(f);
                }
                name5 = n5;
            }

        }
        // Method to load values for drawing pie chart
        // Note : Method LoadValues(...) will load data for Line chart , column chart and scatter chart
        //        These charts require more than 1 array of values to be drawn.
        //        But pie chart requires only 1 array of values and 1 array of names for these values.
        //        So the signature differs for loading values for pie chart and other charts.
        // Input : an array of values and an array of names for these values
        // Output : void
        public void LoadValuesForPie(float[] values, string[] names)
        {
            pieValues.Clear();
            pieNames.Clear();

            if (values != null)
            {
                foreach (float f in values)
                {
                    pieValues.Add(f);
                }
            }
            if (names != null)
            {
                foreach (string s in names)
                {
                    pieNames.Add(s);
                }
            }

        }





    }
}
